#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <chrono>

// 测试结果结构
struct TestResult {
    std::string name;
    bool passed;
    std::string error;
};

class EchoServerTester {
private:
    std::string host;
    int port;
    std::vector<TestResult> results;

public:
    EchoServerTester(const std::string& host = "127.0.0.1", int port = 8081)
        : host(host), port(port) {}

    // 运行所有测试
    void runAllTests() {
        runTest("Basic Echo", [this]() { testBasicEcho(); });
        runTest("Multiple Messages", [this]() { testMultipleMessages(); });
        runTest("Large Message", [this]() { testLargeMessage(); });
        runTest("Concurrent Connections", [this]() { testConcurrentConnections(20); });

        // 输出汇总结果
        std::cout << "\n===== 测试汇总 =====" << std::endl;
        int passedCount = 0;
        for (const auto& result : results) {
            std::cout << "[" << (result.passed ? "PASS" : "FAIL") << "] " << result.name;
            if (!result.passed) {
                std::cout << " - " << result.error;
            }
            std::cout << std::endl;
            if (result.passed) passedCount++;
        }
        std::cout << "总测试数: " << results.size() << ", 通过: " << passedCount 
                  << ", 失败: " << results.size() - passedCount << std::endl;
    }

private:
    // 测试执行器
    void runTest(const std::string& name, std::function<void()> testFunc) {
        std::cout << "执行测试: " << name << "..." << std::endl;
        TestResult result{name, true, ""};
        
        try {
            testFunc();
        } catch (const std::exception& e) {
            result.passed = false;
            result.error = e.what();
        } catch (...) {
            result.passed = false;
            result.error = "未知异常";
        }
        
        results.push_back(result);
    }

    // 创建套接字并连接到服务器
    int connectToServer() {
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) {
            throw std::runtime_error("创建套接字失败");
        }

        struct sockaddr_in serverAddr;
        memset(&serverAddr, 0, sizeof(serverAddr));
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = htons(port);
        
        if (inet_pton(AF_INET, host.c_str(), &serverAddr.sin_addr) <= 0) {
            close(sockfd);
            throw std::runtime_error("无效的服务器地址");
        }

        if (connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
            close(sockfd);
            throw std::runtime_error("连接服务器失败");
        }

        return sockfd;
    }

    // 发送消息并接收响应
    std::string sendAndReceive(const std::string& message) {
        int sockfd = connectToServer();
        
        // 发送消息
        if (send(sockfd, message.c_str(), message.size(), 0) != static_cast<ssize_t>(message.size())) {
            close(sockfd);
            throw std::runtime_error("发送消息失败");
        }

        // 接收响应
        char buffer[1024];
        std::string response;
        ssize_t bytesRead;
        
        // 设置非阻塞读取（超时5秒）
        fd_set readfds;
        struct timeval timeout;
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        while (true) {
            FD_ZERO(&readfds);
            FD_SET(sockfd, &readfds);
            
            int activity = select(sockfd + 1, &readfds, NULL, NULL, &timeout);
            if (activity < 0) {
                close(sockfd);
                throw std::runtime_error("select错误");
            }
            
            if (activity == 0) {
                // 超时
                break;
            }
            
            bytesRead = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
            if (bytesRead <= 0) {
                // 连接关闭或错误
                break;
            }
            
            buffer[bytesRead] = '\0';
            response += buffer;
        }

        close(sockfd);
        return response;
    }

    // 测试基本回显功能
    void testBasicEcho() {
        std::string message = "Hello, server!";
        std::string response = sendAndReceive(message);
        
        if (response != message) {
            throw std::runtime_error("回显内容不匹配: 发送='" + message + "', 接收='" + response + "'");
        }
    }

    // 测试多条消息
    void testMultipleMessages() {
        std::vector<std::string> messages = {"Msg1", "Msg2", "Msg3", "Longer message with spaces and numbers 12345"};
        
        for (const auto& msg : messages) {
            std::string response = sendAndReceive(msg);
            if (response != msg) {
                throw std::runtime_error("回显内容不匹配: 发送='" + msg + "', 接收='" + response + "'");
            }
        }
    }

    // 测试大消息
    void testLargeMessage() {
        std::string largeMessage(1024 * 10, 'A');  // 10KB的消息
        std::string response = sendAndReceive(largeMessage);
        
        if (response != largeMessage) {
            throw std::runtime_error("大消息回显失败: 长度不匹配");
        }
    }

    // 测试并发连接
    void testConcurrentConnections(int numClients) {
        auto clientTask = [this](int id) {
            std::string message = "Client-" + std::to_string(id);
            std::string response = sendAndReceive(message);
            
            if (response != message) {
                throw std::runtime_error("并发测试失败: 发送='" + message + "', 接收='" + response + "'");
            }
        };

        std::vector<std::thread> threads;
        for (int i = 0; i < numClients; ++i) {
            threads.emplace_back(clientTask, i);
        }

        for (auto& t : threads) {
            t.join();
        }
    }
};

int main() {
    try {
        EchoServerTester tester("127.0.0.1", 8081);
        tester.runAllTests();
        return 0;
    } catch (const std::exception& e) {
        std::cerr << "测试框架错误: " << e.what() << std::endl;
        return 1;
    }
}